今天來上一下昨天未完成的邏輯部分
import React, { useState, useRef, useEffect } from "react";
import { TabMenu } from 'primereact/tabmenu';
import { MenuItem } from 'primereact/menuitem';
import { TabView, TabPanel } from 'primereact/tabview';
const TabCompnent: React.FC = () => {
const [activeIndex, setActiveIndex] = useState<number>(0);
const [currLeft, setCurrLeft] = useState<number>(0);
const [currLeft1, setCurrLeft1] = useState<number>(0);
const menuRef = useRef<HTMLDivElement>(null);
const viewRef = useRef<HTMLDivElement>(null);
const [menuPos, setMenuPos] = useState<number[]>([]);
const [viewPos, setViewPos] = useState<number[]>([]);
const items: MenuItem[] = [
{ label: 'Dashboard', icon: 'pi pi-home' },
{ label: 'Transactions', icon: 'pi pi-chart-line' },
{ label: 'Products', icon: 'pi pi-list' },
{ label: 'Messages', icon: 'pi pi-inbox' },
{ label: 'Dashboard1Dashboard1Dashboard1', icon: 'pi pi-home' },
{ label: 'Transactions1Transactions1Transactions1', icon: 'pi pi-chart-line' },
{ label: 'Products1', icon: 'pi pi-list' },
{ label: 'Messages1Messages1Messages1', icon: 'pi pi-inbox' }
];
useEffect(() => {
if (menuRef.current) {
const tabItems: NodeListOf<HTMLLIElement> = menuRef.current.querySelectorAll('.p-tabmenuitem');
let len = tabItems.length
if (len > 0) {
let tabList: number[] = [];
let w = 0;
tabList.push(0)
for (let i = 0; i < len; i++) {
w += tabItems[i].offsetWidth
tabList.push(w)
}
setMenuPos(tabList)
}
}
if (viewRef.current) {
const tabItems: NodeListOf<HTMLLIElement> = viewRef.current.querySelectorAll('.p-unselectable-text');
let len = tabItems.length
if (len > 0) {
let tabList: number[] = [];
let w = 0;
tabList.push(0)
for (let i = 0; i < len; i++) {
w += tabItems[i].offsetWidth
tabList.push(w)
}
setViewPos(tabList)
}
}
}, [])
const handleMenuLeft = () => {
if (!menuRef.current) return;
let inx = menuPos.indexOf(currLeft)
if (inx > 0) {
setCurrLeft((menuPos[inx - 1]))
menuRef.current?.querySelectorAll('.p-tabmenu')[0].scrollTo({
left: menuPos[inx - 1],
behavior: 'smooth'
});
}
}
const handleMenuRight = () => {
if (!menuRef.current) return;
let inx = menuPos.indexOf(currLeft)
let totalW = menuPos[menuPos.length - 1]
if ((totalW - menuRef.current.offsetWidth) < currLeft) return;
setCurrLeft((menuPos[inx + 1]))
menuRef.current?.querySelectorAll('.p-tabmenu')[0].scrollTo({
left: menuPos[inx + 1],
behavior: 'smooth'
});
}
const handleViewLeft = () => {
if (!viewRef.current) return;
let inx = viewPos.indexOf(currLeft1)
if (inx > 0) {
setCurrLeft1(viewPos[inx - 1])
viewRef.current?.querySelectorAll('.p-tabview-nav-content')[0].scrollTo({
left: viewPos[inx - 1],
behavior: 'smooth'
});
}
}
const handleViewRight = () => {
if (!viewRef.current) return;
let inx = viewPos.indexOf(currLeft1)
let totalW = viewPos[viewPos.length - 1]
if ((totalW - viewRef.current?.offsetWidth) < currLeft1) return;
setCurrLeft1((viewPos[inx + 1]))
viewRef.current?.querySelectorAll('.p-tabview-nav-content')[0].scrollTo({
left: viewPos[inx + 1],
behavior: 'smooth'
});
}
return (
<div>
<div className="p-tabmenu-cus">
<div className="p-leftbtn" onClick={handleMenuLeft} />
<div ref={menuRef} style={{ overflow: 'hidden' }}><TabMenu model={items} activeIndex={activeIndex} onTabChange={(e) => setActiveIndex(e.index)} /></div>
<div className="p-rightbtn" onClick={handleMenuRight} />
</div>
<div className="p-tabview-cus">
<div className="p-leftbtn" onClick={handleViewLeft} />
<div ref={viewRef} style={{ overflow: 'hidden' }}>
<TabView pt={{ panelContainer: { hidden: true } }}>
{items.map((tab: MenuItem) => {
return (
<TabPanel key={`${tab.label}_`} leftIcon={`${tab.icon} mr-2`} header={tab.label} />
);
})}
</TabView>
</div>
<div className="p-rightbtn" onClick={handleViewRight} />
</div>
</div>
);
}
export default TabCompnent;
因為在點左點右時都要去找item寬度,避免每次都還要詢問一次,
所以在剛載入好時,將項目的left位置記憶好,
但因為RWD關係,所以只能在點擊當下判斷當前能顯示的寬度
至於其他的部分,我建議是不要直接取primereact class
而是用pt幫控制項目添加獨有className
主要添加各元件上管理方便
以tabmenu 來說 item的部分 可以在pt的menuitem添加className
而 scrollTo 則是 可以在 pt root 增加className控制
有遇過也很好玩的,當視窗resize時,就自動定位到當前點選的項目
可以用scrollIntoView 等等呈現
因為只是展示,所以就沒特別的做了
那麼,明天見